package cc.cc4414.cc03.core.security;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

import cc.cc4414.cc03.sys.entity.Authority;
import cc.cc4414.cc03.sys.entity.Resource;
import cc.cc4414.cc03.sys.service.IAuthorityService;
import cc.cc4414.cc03.sys.service.IResourceService;

/**
 * 资源服务配置
 * 
 * @author cc 2018年6月20日
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

	@Autowired
	private IResourceService iResourceService;

	@Autowired
	private IAuthorityService iAuthorityService;

	@Override
	public void configure(HttpSecurity http) throws Exception {
		// 查找所有资源，按url倒序排列，使得优先匹配到不带有通配符的
		List<Resource> resources = iResourceService.listByOrderByUrlDesc();
		for (Resource resource : resources) {
			// 查找该资源对应所有的权限
			List<Authority> authorityList = iAuthorityService.listByResourceId(resource.getId());
			// 将查找到的权限名取出，组成String数组
			String[] authorities = authorityList.stream().map(authority -> authority.getName())
					.toArray(String[]::new);
			// 使用权限表达式配置每个资源所需要的权限
			if (authorities.length != 0) {
				// 如果该资源有对应的权限，则允许这些权限访问
				http.authorizeRequests().antMatchers(HttpMethod.resolve(resource.getMethod()), resource.getUrl())
						.hasAnyAuthority(authorities);
			} else {
				// 若数据库里资源没有对应的权限，则经过认证就能访问
				http.authorizeRequests().antMatchers(HttpMethod.resolve(resource.getMethod()), resource.getUrl())
						.authenticated();
			}
		}
		// 其余所有页面允许所有人访问
		http.authorizeRequests().anyRequest().permitAll();
	}
}
